﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using Microsoft.Win32;
using Cqrs.StateMachineDesigner.CustomCode;

namespace Cqrs.StateMachineDesigner.Generator
{
    /// <summary>
    /// Interaction logic for CodeGenerator.xaml
    /// </summary>
    public partial class CodeGenerator : Window
    {
        public List<EventUiObject> Events { get; set; }
        private string _namespace;
        private string _domainName;
        private IList<DomainProperty> _domainProperties;

        public CodeGenerator()
        {
            InitializeComponent();
        }

        public void ShowForm(string domainNamespace, 
            string domainName, 
            List<CommandEventModel> events, IList<DomainProperty> domainProperties)
        {
            _namespace = domainNamespace;
            _domainName = domainName;
            _domainProperties = domainProperties;

            List<EventUiObject> eventObjects = new List<EventUiObject>();

            events.ForEach(p =>
            {
                EventUiObject evtObj = new EventUiObject(p, true);
                evtObj.PropertyChanged += new PropertyChangedEventHandler((s, e) => Generate());
                eventObjects.Add(evtObj);
            });
            this.Events = eventObjects;
            grdEvents.DataContext = this.Events;
            Generate();
            this.ShowDialog();
        }

        private void Generate()
        {
            txtEvents.Text = "";            
            IList<CommandEventModel> events = new List<CommandEventModel>();
            foreach (EventUiObject @eventUi in (List<EventUiObject>)grdEvents.DataContext)
            {                
                if (@eventUi.IsChecked)
                {
                    CommandEventModel eventModel = @eventUi.CommandEventModel;
                    events.Add(eventModel);
                }
            }
            GeneratorModel generatorModel = new GeneratorModel(_namespace, _domainName, events, _domainProperties);
            txtEvents.Text = new EventClass(generatorModel).TransformText();
            txtDomain.Text = new DomainClass(generatorModel).TransformText();
            txtCommands.Text = new CommandClass(generatorModel).TransformText();
            txtCommandsHandlers.Text = new CommandHandlers(generatorModel).TransformText();
            
        }

        // todo - do we need this and the CommandEventModel object???
        public class EventUiObject : INotifyPropertyChanged
        {
            public EventUiObject(CommandEventModel commandEventModel, 
                bool isChecked)
            {
                CommandEventModel = commandEventModel;
                _isChecked = isChecked;
            }
            private bool _isChecked;
            public CommandEventModel CommandEventModel { get; private set; }
            public bool IsChecked
            {
                get
                {
                    return _isChecked;
                }
                set
                {
                    _isChecked = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
        }

        private void btnGenerate_Click(object sender, RoutedEventArgs e)
        {
            try
            {

                SaveFileDialog saveFile = new SaveFileDialog();
                saveFile.Filter = "C# Files (*.cs)|*.cs";
                saveFile.FileName = _domainName + ".generated.cs";
                if (saveFile.ShowDialog().Value == true)
                {
                    var fileStream = System.IO.File.CreateText(saveFile.FileName);
                    if (string.IsNullOrEmpty(_namespace))
                    {
                        fileStream.Write("namespace {0}", _namespace);
                        fileStream.Write("{");
                    }
                    fileStream.Write(txtDomain.Text);
                    fileStream.Write(txtEvents.Text);
                    fileStream.Write(txtCommands.Text);
                    fileStream.Write(txtCommandsHandlers.Text);
                    if (string.IsNullOrEmpty(_namespace))
                    {
                        fileStream.Write("}");
                    }
                    fileStream.Close();
                }
                
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

    }
}
